package com.atom.module.coroutine.scope

import com.atom.module.coroutine.core.AbstractCoroutine
import kotlinx.coroutines.Job
import kotlin.coroutines.Continuation
import kotlin.coroutines.CoroutineContext
import kotlin.coroutines.startCoroutine
import kotlin.coroutines.suspendCoroutine

// 协程作用域 接口
interface CoroutineScope {

    val scopeContext: CoroutineContext

}

// 环境作用域  实现协程作用域 内部包含一个协程上下文环境
internal class ContextScope : CoroutineScope {

    override val scopeContext: CoroutineContext

    constructor(context: CoroutineContext) {
        scopeContext = context;
    }
}

// 作用域的 + 函数实现 , 实际上 创建新的作用域,使用的是 上下文的+函数实现
operator fun CoroutineScope.plus(context: CoroutineContext): CoroutineScope {
    return ContextScope(scopeContext + context)
}

fun CoroutineScope.cancel() {
    val job = scopeContext[Job]
        ?: error("Scope cannot be cancelled because it does not have a job: $this")
    job.cancel()
}

suspend fun <R> coroutineScope(block: suspend CoroutineScope.() -> R): R {
    return suspendCoroutine { continuation ->
        val coroutine = ScopeCoroutine(continuation.context, continuation)
        block.startCoroutine(coroutine, coroutine)
    }
}

internal open class ScopeCoroutine<T> : AbstractCoroutine<T> {

    protected val continuation: Continuation<T>

    constructor(
        context: CoroutineContext,
        continuation: Continuation<T>
    ) : super(context) {
        this.continuation = continuation;
    }

    override fun resumeWith(result: Result<T>) {
        super.resumeWith(result)
        continuation.resumeWith(result)
    }
}
